github.com/aarzilli/tools@v0.0.0-20151123112009-0d27094f75e0/util/print map recursive.go (about)

     1  package util
     2  
     3  import "fmt"
     4  import "bytes"
     5  
     6  // this does not work generically:
     7  var Map_example_expl_1 map[float64]map[int]float64
     8  
     9  // this is generic - but unnecessary:
    10  var Map_example_expl_2 map[interface{}]map[interface{}]interface{}
    11  
    12  var Map_example_right map[interface{}]interface{}
    13  
    14  func init() {
    15  
    16  	Map_example_expl_1 = map[float64]map[int]float64{
    17  		10:  map[int]float64{0: 0, 1: 2},
    18  		7.5: map[int]float64{0: 0, 1: 1.5},
    19  		5.0: map[int]float64{0: 0, 1: 1},
    20  	}
    21  
    22  	Map_example_expl_2 = map[interface{}]map[interface{}]interface{}{
    23  		10:  map[interface{}]interface{}{0: 0, 1: 2},
    24  		7.5: map[interface{}]interface{}{0: 0, 1: 1.5},
    25  	}
    26  
    27  	Map_example_right = map[interface{}]interface{}{
    28  		"scalar_k1":                        "scalar_val",
    29  		"scalar_k2":                        0.11111,
    30  		"key to invalidly typed submap =>": map[interface{}]float64{"xx": 0.111, 1: 0.5},
    31  		"lvl 1 submap":                     map[interface{}]interface{}{0: 0, 1: 2},
    32  		32168:                              map[interface{}]interface{}{"any type": 0, 1: "anywhere"},
    33  		"lvl 2 submaps": map[interface{}]interface{}{
    34  			"l1a": map[interface{}]interface{}{"l2a": 0, 1: 0.5},
    35  			"l1b": map[interface{}]interface{}{0: 0, 1: 0.5},
    36  			13:    "mixing in a scalar",
    37  		},
    38  	}
    39  
    40  }
    41  
    42  //  PrintMap does print a map without recursion
    43  func PrintMap(m map[interface{}]interface{}) string {
    44  	return PrintMapRecursive(m, 0)
    45  }
    46  
    47  //  PrintMap prints a map - recursing through submaps
    48  // concrete types, like map[float64]map[int]float64
    49  //	  would have to be converted element by element
    50  //   to map[interface{}]interface{}
    51  // the json.indent function might be similar
    52  // but I did not bring it to work
    53  func PrintMapRecursive(m1 map[interface{}]interface{}, depth int) string {
    54  	b1 := new(bytes.Buffer)
    55  	fiveSpaces := "       " // html spaces
    56  	cxIndent := fmt.Sprint(depth * 40)
    57  	depthStyle := ""
    58  	if depth == 0 {
    59  		depthStyle = "margin-top:8px; border-top: 1px solid #aaa;"
    60  	} else {
    61  		darkening := 16 - 2*depth
    62  		bgc := fmt.Sprintf("%x%x%x", darkening, darkening, darkening)
    63  		depthStyle = "margin:0;padding:0;background-color:#" + bgc + ";"
    64  	}
    65  	for k1, m2 := range m1 {
    66  		b1.WriteString("<div style='" + depthStyle + "margin-left:" + cxIndent + "px;'>\n")
    67  		b1.WriteString(fmt.Sprint(k1))
    68  		//b1.WriteString( "<br>\n" )
    69  		switch typedvar := m2.(type) {
    70  		default:
    71  			type_unknown := fmt.Sprintf("<br>\n &nbsp; &nbsp;  --this type switch does not support type %#v", typedvar)
    72  			//panic(type_unknown)
    73  			b1.WriteString(fiveSpaces + fmt.Sprintf("%#v", typedvar) + type_unknown)
    74  		case string:
    75  			b1.WriteString(fiveSpaces + typedvar)
    76  		case int, float64:
    77  			b1.WriteString(fiveSpaces + fmt.Sprint(typedvar))
    78  		case nil:
    79  			b1.WriteString("nil interface")
    80  		case map[interface{}]interface{}:
    81  			b1.WriteString(PrintMapRecursive(typedvar, depth+1))
    82  		}
    83  		b1.WriteString("<br>\n")
    84  		b1.WriteString("</div>\n")
    85  	}
    86  	return b1.String()
    87  }
    88  
    89  /*
    90  func Test_print_map(t *testing.T){
    91  
    92  	c, err := aetest.NewContext(nil)
    93  	if err != nil {
    94  		t.Errorf("could not get a context")
    95  	}
    96  
    97  	s := PrintMap(Map_example_right)
    98  	c.Infof("testing print map recursive ...")
    99  	if  Test_want != s {
   100  		c.Errorf("want %s - got %s", Test_want, s )
   101  	}
   102  }
   103  */
   104  
   105  const Test_want = `<div style='margin-top:8px; border-top: 1px solid #aaa;margin-left:0px;'>
   106  scalar_k1&nbsp;  &nbsp;  &nbsp;scalar_val<br>
   107  </div>
   108  <div style='margin-top:8px; border-top: 1px solid #aaa;margin-left:0px;'>
   109  scalar_k2&nbsp;  &nbsp;  &nbsp;0.11111<br>
   110  </div>
   111  <div style='margin-top:8px; border-top: 1px solid #aaa;margin-left:0px;'>
   112  key to invalidly typed submap =>&nbsp;  &nbsp;  &nbsp;map[interface {}]float64{"xx":0.111, 1:0.5}<br>
   113   &nbsp; &nbsp;  --this type switch does not support type map[interface {}]float64{"xx":0.111, 1:0.5}<br>
   114  </div>
   115  <div style='margin-top:8px; border-top: 1px solid #aaa;margin-left:0px;'>
   116  lvl 1 submap<div style='margin:0;padding:0;background-color:#eee;margin-left:40px;'>
   117  0&nbsp;  &nbsp;  &nbsp;0<br>
   118  </div>
   119  <div style='margin:0;padding:0;background-color:#eee;margin-left:40px;'>
   120  1&nbsp;  &nbsp;  &nbsp;2<br>
   121  </div>
   122  <br>
   123  </div>
   124  <div style='margin-top:8px; border-top: 1px solid #aaa;margin-left:0px;'>
   125  32168<div style='margin:0;padding:0;background-color:#eee;margin-left:40px;'>
   126  any type&nbsp;  &nbsp;  &nbsp;0<br>
   127  </div>
   128  <div style='margin:0;padding:0;background-color:#eee;margin-left:40px;'>
   129  1&nbsp;  &nbsp;  &nbsp;anywhere<br>
   130  </div>
   131  <br>
   132  </div>
   133  <div style='margin-top:8px; border-top: 1px solid #aaa;margin-left:0px;'>
   134  lvl 2 submaps<div style='margin:0;padding:0;background-color:#eee;margin-left:40px;'>
   135  l1a<div style='margin:0;padding:0;background-color:#ccc;margin-left:80px;'>
   136  l2a&nbsp;  &nbsp;  &nbsp;0<br>
   137  </div>
   138  <div style='margin:0;padding:0;background-color:#ccc;margin-left:80px;'>
   139  1&nbsp;  &nbsp;  &nbsp;0.5<br>
   140  </div>
   141  <br>
   142  </div>
   143  <div style='margin:0;padding:0;background-color:#eee;margin-left:40px;'>
   144  l1b<div style='margin:0;padding:0;background-color:#ccc;margin-left:80px;'>
   145  0&nbsp;  &nbsp;  &nbsp;0<br>
   146  </div>
   147  <div style='margin:0;padding:0;background-color:#ccc;margin-left:80px;'>
   148  1&nbsp;  &nbsp;  &nbsp;0.5<br>
   149  </div>
   150  <br>
   151  </div>
   152  <div style='margin:0;padding:0;background-color:#eee;margin-left:40px;'>
   153  13&nbsp;  &nbsp;  &nbsp;mixing in a scalar<br>
   154  </div>
   155  <br>
   156  </div>
   157  `